<?php

namespace App\Services\Bank;

use App\Services\Bank\BankOfHangzhou\BankOfHangzhouClient;
use App\Services\Bank\BankOfHangzhou\BankOfHangzhouConfig;
use App\Services\Bank\BankOfHangzhou\BankOfHangzhouService;
use InvalidArgumentException;

class BankServiceFactory
{
    /**
     * 创建银行服务实例
     *
     * @param string $bankName 银行名称
     * @return BankServiceInterface
     * @throws InvalidArgumentException
     */
    public static function make(string $bankName): BankServiceInterface
    {
        $bankConfig = config("bank.banks.{$bankName}");

        if (empty($bankConfig)) {
            throw new InvalidArgumentException("未找到银行配置: {$bankName}");
        }

        $driver = $bankConfig['driver'] ?? $bankName;

        switch ($driver) {
            case 'BankOfHangzhou':
                return self::createBankOfHangzhouService($bankConfig);

            default:
                throw new InvalidArgumentException("不支持的银行驱动: {$driver}");
        }
    }

    /**
     * 获取默认银行服务
     *
     * @return BankServiceInterface
     */
    public static function default(): BankServiceInterface
    {
        $defaultBank = config('bank.default');
        return self::make($defaultBank);
    }

    /**
     * 创建杭州银行服务实例
     *
     * @param array $config
     * @return BankOfHangzhouService
     */
    private static function createBankOfHangzhouService(array $config): BankOfHangzhouService
    {
        $bankConfig = new BankOfHangzhouConfig(
            $config['erp_sys_code'],
            $config['cust_no'],
            [
                'timeout' => $config['timeout'] ?? 30,
                'charset' => $config['charset'] ?? 'UTF-8',
                'message_type' => $config['message_type'] ?? '01',
                'with_header' => $config['with_header'] ?? false,
            ]
        );

        $client = new BankOfHangzhouClient($bankConfig);
        return new BankOfHangzhouService($client);
    }

    /**
     * 获取所有可用银行列表
     *
     * @return array
     */
    public static function getAvailableBanks(): array
    {
        return array_keys(config('bank.banks', []));
    }

    /**
     * 检查银行是否可用
     *
     * @param string $bankName
     * @return bool
     */
    public static function isAvailable(string $bankName): bool
    {
        return in_array($bankName, self::getAvailableBanks());
    }
}